package wave.robot.second;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.logging.Logger;

import com.google.wave.api.AbstractRobotServlet;
import com.google.wave.api.Blip;
import com.google.wave.api.Event;
import com.google.wave.api.RobotMessageBundle;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;

@SuppressWarnings("serial")
public class SecondWaveRobotServlet
        extends
        AbstractRobotServlet
{
    private final String HOME_URL =
            "http://lesner-second-wave-robot.appspot.com/";

    private static final Logger log =
            Logger
                    .getLogger(SecondWaveRobotServlet.class
                            .getName());

    private static String USAGE_INSTRUCTIONS =
            "/event Vacation /start 2008/08/12 /end 2008/08/29 /location Palo Alto, 94303 /details Tour of Silicon Valley";

    // How to integrate with voting app?
    // Item app?
    
    @Override
    public void processEvents(
            RobotMessageBundle robotMessageBundle)
    {
        Wavelet wavelet =
                robotMessageBundle
                        .getWavelet();

        if (robotMessageBundle
                .wasSelfAdded())
        {
            processWaveletSelfAddedEvent(wavelet);
        }
        else
        {
            for (Event event : robotMessageBundle
                    .getBlipSubmittedEvents())
            {
                processBlipSubmittedEvent(event
                        .getBlip());
            }
        }
    }

    private void processWaveletSelfAddedEvent(
            Wavelet wavelet)
    {
        Blip blip =
                wavelet
                        .appendBlip();

        TextView textView =
                blip
                        .getDocument();

        textView
                .append(USAGE_INSTRUCTIONS);
    }

    private void processBlipSubmittedEvent(
            Blip blip)
    {
        String response =
                null;

        String blipDocumentText =
                null;

        if (blip
                .getBlipId()
                .equals(
                        blip
                                .getWavelet()
                                .getRootBlipId()))
        {
            blipDocumentText =
                    blip
                            .getWavelet()
                            .getTitle();
        }
        else
        {
            blipDocumentText =
                    blip
                            .getDocument()
                            .getText();
        }

        log
                .info("Received blip: '"
                        + blipDocumentText
                        + "'");

        if (blipDocumentText != null)
        {
            Map<String, StringBuilder> map =
                    new StringAttributeMapFn()
                            .apply(blipDocumentText);

            if (map
                    .size() > 0
                    && map
                            .containsKey("/event")
                    && !map
                            .containsKey("/calendar"))
            {
                response =
                        generateResponseForEvent(map);
            }
        }

        if (response != null)
        {
            blip
                    .getDocument()
                    .append(
                            response);
        }

        log
                .info("Outgoing response: "
                        + response);
    }

    private String generateResponseForEvent(
            Map<String, StringBuilder> map)
    {
        log
                .info("Event map: "
                        + map);

        return ""
                + " /calendar "
                + "<a href=\""
                // + "http://www.google.com/calendar/event?action=TEMPLATE&text=September+Meeting:+Topic+TBD&dates=20090903T010000Z/20090903T020000Z&location=Mountain+View,+CA+94043&sprop=website:http://www.meetup.com/sv-gtug/calendar/10863204/&sprop=name:Silicon+Valley+Google+Technology+User+Group&details=For+full+details,+including+the+address,+and+to+RSVP+see:%0ahttp://www.meetup.com/sv-gtug/calendar/10863204/%0aSilicon+Valley+Google+Technology+User+Group%0aWe+will+be+meeting+at+the+normal+time+in+the+usual+place+in+September.+The+topic+is+yet+to+be+determined."
                + "http://www.google.com/calendar/event?action=TEMPLATE"
                + makeGoogleEventParameters(map)
                + "\">"
                + "<img src=\""
                + "http://static1.meetupstatic.com/2186963615957476/img/calendar_google.png"
                + "\"></img>"
                + "</a>"
                + ""
                + "<a href=\""
                + HOME_URL
                + "outlookcalendarservlet?action=create"
                + makeOutlookEventParameters(map)
                + "\">"
                + "<img src=\""
                + "http://static2.meetupstatic.com/50031244505240516014032/img/calendar_outlook.gif"
                + "\"></img>"
                + "</a>"

                + ""
                + "<a href=\""
                + HOME_URL
                + "outlookcalendarservlet?action=create"
                + makeOutlookEventParameters(map)
                + "\">"
                + "<img src=\""
                + "http://static2.meetupstatic.com/55575252582590535659/img/calendar_ical.png"
                + "\"></img>"
                + "</a>"
                + ""
                + ""
                + "<a href=\""
                + makeYahooEventUrl(map)
                + "\">"
                + "<img src=\""
                + "http://static1.meetupstatic.com/6457860817470504/img/calendar_yahoo.png"
                + "\"></img>"
                + "</a>"
                + "";
    }

    private String makeYahooEventUrl(
            Map<String, StringBuilder> map)
    {
        String result =
                "http://calendar.yahoo.com/?v=60&VIEW=d&in_loc=Googleplex+(Bldg.+43)&in_csz=Mountain+View%2c+CA+94043&type=20&TITLE=September+Meeting%3a+Topic+TBD&ST=20090903T010000Z&DUR=0100&URL=http%3a%2f%2fwww.meetup.com%2fsv-gtug%2fcalendar%2f10863204%2f&DESC=For+full+details%2c+including+the+address%2c+and+to+RSVP+see%3a%0ahttp%3a%2f%2fwww.meetup.com%2fsv-gtug%2fcalendar%2f10863204%2f%0aSilicon+Valley+Google+Technology+User+Group%0aWe+will+be+meeting+at+the+normal+time+in+the+usual+place+in+September.+The+topic+is+yet+to+be+determined....";

        result =
                "http://calendar.yahoo.com/?v=60&VIEW=d"
                        + "&in_loc="

                        + getStringFromMap(
                                map,
                                "/location")
                        + "&type=20"
                        + "&TITLE="
                        + getStringFromMap(
                                map,
                                "/event")
                        + "&ST="
                        + getDateFromMap(
                                map,
                                "/start")
                        + "&DESC="
                        + getStringFromMap(
                                map,
                                "/details");

        return result;
    }

    private String makeOutlookEventParameters(
            Map<String, StringBuilder> map)
    {
        String result =
                ""
                        + "&event=September+Meeting:+Topic+TBD"
                        + "&start=20090903T010000Z"
                        + "&end=20090903T020000Z"
                        + "&location=Mountain+View,+CA+94043"
                        + "&details=For+full+details,+including+the+address,+and+to+RSVP+see:%0ahttp://www.meetup.com/sv-gtug/calendar/10863204/%0aSilicon+Valley+Google+Technology+User+Group%0aWe+will+be+meeting+at+the+normal+time+in+the+usual+place+in+September.+The+topic+is+yet+to+be+determined.";

        result =
                ""
                        + "&event="
                        + getStringFromMap(
                                map,
                                "/event")
                        + "&start="
                        + getDateFromMap(
                                map,
                                "/start")
                        + "&end="
                        + getDateFromMap(
                                map,
                                "/end")
                        + "&location="
                        + getStringFromMap(
                                map,
                                "/location")
                        + "&details="
                        + getStringFromMap(
                                map,
                                "/details");

        return result;
    }

    private String makeGoogleEventParameters(
            Map<String, StringBuilder> map)
    {
        String result =
                ""
                        + "&text=September+Meeting:+Topic+TBD"
                        + "&dates=20090903T010000Z/20090903T020000Z"
                        + "&location=Mountain+View,+CA+94043"
                        + "&sprop=website:http://www.meetup.com/sv-gtug/calendar/10863204/"
                        + "&sprop=name:Silicon+Valley+Google+Technology+User+Group"
                        + "&details=For+full+details,+including+the+address,+and+to+RSVP+see:%0ahttp://www.meetup.com/sv-gtug/calendar/10863204/%0aSilicon+Valley+Google+Technology+User+Group%0aWe+will+be+meeting+at+the+normal+time+in+the+usual+place+in+September.+The+topic+is+yet+to+be+determined.";

        result =
                ""
                        + "&text="
                        + getStringFromMap(
                                map,
                                "/event")
                        + "&dates="
                        + getDateFromMap(
                                map,
                                "/start")
                        + "/"
                        + getDateFromMap(
                                map,
                                "/end")
                        + "&location="
                        + getStringFromMap(
                                map,
                                "/location")
                        + "&details="
                        + getStringFromMap(
                                map,
                                "/details");

        return result;
    }

    String dateFormat(
            Date date)
    {
        return new SimpleDateFormat(
                "yyyyMMdd HHmmss")
                .format(
                        date)
                .replaceFirst(
                        " ",
                        "T")
                + "Z";
    }

    @SuppressWarnings("deprecation")
    private String getDateFromMap(
            Map<String, StringBuilder> map,
            String key)
    {
        try
        {
            return dateFormat(new Date(
                    map
                            .get(
                                    key)
                            .toString()));
        }
        catch (Exception exception)
        {
            return dateFormat(new Date());
        }
    }

    private String getStringFromMap(
            Map<String, StringBuilder> map,
            String key)
    {
        if (!map
                .containsKey(key))
        {
            return "";

        }

        return encode(map
                .get(
                        key)
                .toString()
                .trim());
    }

    String encode(
            String input)
    {
        return input
                .replaceAll(
                        " ",
                        "+")
                .replaceAll(
                        "\t",
                        "+")
                .replaceAll(
                        ":",
                        "%3a")
                .replaceAll(
                        "/",
                        "%2f");
    }

}
